require "irc"
require "tcl_bot/commands"

module TclBot
  class Connection < IRC::Connection
    include *TclBot::Commands::command_modules
    
    attr_reader :interp

    def initialize(server, port, options = {})
      @filename = options[:filename]
      initialize_interpreter
      super
    end

    def on_privmsg
      if script = response.text[/^tcl (.*)$/, 1]
        channel = response.args.first
        next unless channel[/^#/]
        send_message(channel, interp_eval(script))
      
      elsif response.text[/^#{Process.pid} save/]
        nick = response.from[/^(.*?)!/, 1]
        save_state
        send_message(nick, "saved interpreter state")
        
      elsif response.text[/^#{Process.pid} raw (.*)/]
        send_line $1
        
      end
    end
    
    def save_state
      File.open(filename, "w") do |file|
        file.write(interp.to_tcl)
      end
    end
    
    protected
      attr_reader :filename
    
      def initialize_interpreter
        @interp = RemoteInterp.new(filename)
        @interp.delegate = self
        methods.each do |method|
          @interp.expose($1) if method =~ /^tcl_(.*)/
        end
      end
    
      def interp_eval(script)
        interp.eval(script, :timeout => 5, :limit => 2**16)
      rescue StandardError => e
        "error: #{e}"
      end
      
      def send_message(channel, message)
        message.split("\n")[0, 10].each do |line|
          send_line "PRIVMSG #{channel} :#{line}"
        end
      end
  end
end
